Шаг 3 - События рамки окна

Загрузить проект

Создание проекта

Продолжаем развитие нашего проекта дальше. Можете опять скопировать файл, как мы это делали в предыдущем шаге.

Создаем код

В описание рамки окна необходимо внести следующие изменения:

class CMainWnd : public CFrameWnd
{
public:
        CMainWnd();
        afx_msg void OnLButtonDblClk(UINT, CPoint);     // виртуальная процедура ответа на левую кнопку
        afx_msg void OnRButtonDblClk(UINT, CPoint);     // виртуальная процедура ответа на правую кнопку
        afx_msg void OnKeyDown(UINT, UINT, UINT);       // виртуальная процедура ответа на клавишу
        ~CMainWnd();    // деструктор
private:
        CStatic* MyStatic;
        CButton* MyButton;
        CEdit* MyEdit;
        DECLARE_MESSAGE_MAP(); // таблица откликов
};

И вписать следующие процедуры после описания класса.

BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)     // таблица откликов на сообщения
ON_WM_LBUTTONDBLCLK()   // реакция на нажатие левой кнопки мыши
ON_WM_RBUTTONDBLCLK()   // реакция на нажатие правой кнопки мышки
ON_WM_KEYDOWN()         // реакция на нажатие клавиши
END_MESSAGE_MAP()
void CMainWnd::OnKeyDown(UINT, UINT, UINT)
{
        AfxMessageBox(" Key Button Down ");
}
void CMainWnd::OnRButtonDblClk(UINT, CPoint)
{
        AfxMessageBox(" Rigth Button Click ");
}
void CMainWnd::OnLButtonDblClk(UINT, CPoint)
{
        AfxMessageBox(" Left Button Click ");
}

Описание

Помимо наличия окна и элементов управления неплохо, если программа в виде класса окна сможет реагировать на события. Windows порождает кучу событий, если вы двигаете мышку, нажимаете клавишу или пьете кофе, операционная среда знает все. Свои знания о ситуации она передает с помощью сообщений. На программу сообщения льются непрекращаемым потоком. Нам из этого потока необходимо выбрать нужные и обработать.

Добавление в класс макроса DECLARE_MESSAGE_MAP() говорит о том, что данный класс будет реагировать на события.

Если класс реагирует на события, то необходимо описать таблицу откликов на них. Таблица откликов находится между определениями BEGIN_MESSAGE_MAP(Класс реагирующий, Класс родитель) и END_MESSAGE_MAP(). Зачем при определении таблицы откликов указывать класс, который будет производить реакцию? Но таблиц откликов может быть много для разных классов и как интересно компилятор разберется, кому она принадлежит? Класс родителя необходим для обработки стандартных сообщений, даже если вы их явно не обрабатываете, например, закрыть приложение.

Между этими определениями вы пишете реакцию. В MFC предусмотрена обработка кучи событий, и их описание начинается с ON_WM_message. В нашем случае это стандартные события WINDOWS по реакции на нажатие клавиш и мыши.

Для каждого стандартного события описана виртуальная функция, которая будет вызываться при его возникновении. Имя и параметры этой функции строго определены и ошибаться здесь нельзя. Правило выглядит так: хочешь реакцию на стандартное событие - опиши его в таблице откликов и замени виртуальную процедуру. Afxmsg воспринимайте как аналог virtual.

После описания всех функций необходимо их реально создать, что и делается далее. AfxMessageBox() - это вызов простого диалогового окна с надписью. Результат двойного щелчка мышкой смотрите на картинке ниже.

3_1.gif (2825 b)

Шпаргалка

  1. Указать классу, что он реагирует на события:
    DECLARE_MESSAGE_MAP();
  2. Создать таблицу откликов на события:
    BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)
    ......
    END_MESSAGE_MAP()
  3. Описать процедуры, соответствующие таблице, в классе, реагирующем на события:
    afx_msg void OnLButtonDblClk(UINT, CPoint);
    ......
  4. Создать реализацию событий:
    void CMainWnd::OnKeyDown(UINT, UINT, UINT)
    {
            AfxMessageBox(" Key Button Down ");
    }
    
  5. Дальше Вам известно. Результат превосходит все ожидания. Только не забудьте, что реакция мышки на двойной щелчок.
Hosted by uCoz